package com.liry.security.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * security认证配置
 *
 * @author ALI
 * @since 2023/5/29
 */
@Configuration
@EnableWebSecurity
public class SecurityWebConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("ali")
            .password(passwordEncoder().encode("123456"))
            .roles("admin");
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 表单
        http
            .formLogin()
            // 自定义登录页
            .loginPage("/login.html")
            // 登录的请求接口，对应表单的action，这里只是修改了处理的api，实际处理还是security
            .loginProcessingUrl("/loginDeal")
            // 不能写：successForwardUrl("/index.html")，会报405
            .defaultSuccessUrl("/index.html")
            // 登录失败转发到哪个页面
            .failureForwardUrl("/login.html?error=true")
            // 登录的用户名和密码参数名称
            .usernameParameter("username")
            .passwordParameter("pwd")
            .successHandler(new LoginSuccessHandler())
            .failureHandler(new LoginFailureHandler())
            .permitAll()
            // 开启认证
            .and().authorizeRequests()
            //设置哪些路径可以直接访问，不需要认证
            .antMatchers("/test/*").permitAll()
            //需要认证
            .anyRequest().authenticated()
            .and().csrf().disable(); //关闭csrf防护
    }
}
